/*
 * Copyright 2011 Mark Davidson.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package org.dctmcommons;

import java.util.ArrayList;
import java.util.List;

import org.dctmcommons.impl.ObjectHelper;
import org.junit.*;

import com.documentum.fc.client.IDfFolder;
import com.documentum.fc.client.IDfSession;
import com.documentum.fc.common.DfException;

import static org.junit.Assert.*;
import static org.hamcrest.Matchers.*;

/**
 * Integration tests for {@link ObjectHelper}.
 */
public class ObjectHelperIT {
	
	/** The applicatins folder path. */
	private static final String APPS_FOLDER_PATH = "/System/Applications";
	
	/** The {@link ObjectHelper} instance. */
	private IObjectHelper objectHelper = null;
	
	/**
	 * Tests the factory method.
	 */
	@Test
	public void testGetInstance() {
		System.out.println(">>> testGetInstance");
		assertThat("Factory method returned null",
				   objectHelper,
				   is(notNullValue()));
	}

	/**
	 * Tests getPrimaryFolderDetails method.
	 * @throws DfException The repository exception
	 */
	@Test
	public void testGetPrimaryFolderDetails() throws DfException {
		System.out.println(">>> testGetPrimaryFolderDetail");
		
		final IDfSession session = DctmCommonsTestUtil.getSession();
		
		final IDfFolder folder = session.getFolderByPath(APPS_FOLDER_PATH);
		
		final String[] parent = objectHelper.getPrimaryFolderDetails(
												session,
												folder.getObjectId().getId());
		assertThat("Folder details is null", parent, is(notNullValue()));
		assertThat("Invalid size of folder details array",
				   parent.length,
				   is(3));
		assertThat("Incorrect folder name: ", parent[0], is(notNullValue()));
		assertThat("Incorrect folder name: ", parent[1], is("/System"));
		assertThat("Incorrect folder name: ", parent[2], is("System"));
		
		DctmCommonsTestUtil.releaseSession();
	}
	
	/**
	 * Tests path building.
	 * @throws DfException The repository exception
	 */
	@Test
	public void testBuild() throws DfException {
		System.out.println(">>> testBuild");
		
		IDfFolder folder = null;
		String testFolderPath = null;
		final DctmCommonsTestContext ctx = DctmCommonsTestUtil.getContext();
		final IDfSession session = ctx.getSession();
		
		session.beginTrans();
		try {
			testFolderPath = DctmCommonsTestUtil.createTestFolderPath();
			
			System.out.println("Got test folder path: " + testFolderPath);
			
			folder = objectHelper.mkdirs(session,
										 testFolderPath + "/folder1/folder2",
										 null,
										 null);
			session.commitTrans();
		} catch (DfException e) {
			session.abortTrans();
		}
		
		assertThat("Folder object is null",
				   folder,
				   is(notNullValue()));
		
		assertThat("Folder name is incorrect",
				   folder.getObjectName(),
				   is("folder2"));
		
		assertThat("Folder path is incorrect",
				   folder.getFolderPath(0),
				   is(testFolderPath + "/folder1/folder2"));

		DctmCommonsTestUtil.teardown(testFolderPath, true);
		assertThat("Failed to remove test folder",
				   session.getFolderByPath(testFolderPath),
				   is(nullValue()));
		
		DctmCommonsTestUtil.releaseSession();
	}
	
	/**
	 * Tests path building using a base path.
	 * @throws DfException The repository exception
	 */
	@Test
	public void testBuildFromBasePath() throws DfException {
		System.out.println(">>> testBuildFromBasePath");
		
		IDfFolder folder = null;
		String testFolderPath = null;
		final IDfSession session = DctmCommonsTestUtil.getSession();
		
		session.beginTrans();
		try {
			testFolderPath = DctmCommonsTestUtil.createTestFolderPath();
			
			System.out.println("Got test folder path: " + testFolderPath);
			
			folder = objectHelper.mkdirs(session,
										 testFolderPath,
										 "folder1/folder2",
										 null,
										 null);
			session.commitTrans();
		} catch (DfException e) {
			session.abortTrans();
		}
		
		assertThat("Folder object is null",
				   folder,
				   is(notNullValue()));
		
		assertThat("Folder name is incorrect",
				   folder.getObjectName(),
				   is("folder2"));
		
		assertThat("Folder path is incorrect",
				   folder.getFolderPath(0),
				   is(testFolderPath + "/folder1/folder2"));

		DctmCommonsTestUtil.teardown(testFolderPath, true);
		assertThat("Failed to remove test folder",
				   session.getFolderByPath(testFolderPath),
				   is(nullValue()));
		
		DctmCommonsTestUtil.releaseSession();
	}
	
	/**
	 * Tests repository walking.
	 * @throws DfException The repository exception
	 */
	@Test 
	public void testWalk() throws DfException {
		System.out.println(">>> testWalk");
		
		final List<String> foundObjects = new ArrayList<String>();
		final IDfSession session = DctmCommonsTestUtil.getSession();
		
		objectHelper.walk(session, "/System", true,
						  new ICoreObjectInfoCallback() {
			@Override
			public boolean read(final ICoreObjectInfo info)
				throws DfException {
				
				assertThat("Core object info is null",
						   info, is(notNullValue()));
				/*
				System.out.println("Got object: " +
									info.getObjectPath() + " : " +
									info.getObjectType());
				*/
				
				if (info.getObjectType().equals("dm_xml_config")) {
					// should fire first
					foundObjects.add("dm_xml_config");
					return true;
				} else if (info.getObjectName().equals("Presets")) {
					// should fire second
					foundObjects.add("Presets");
					return true;
				} else if (info.getObjectName()
										.equals("Workflow Customizations")) {
					// should never fire
					foundObjects.add("Workflow Customizations");
					return true;
				} else {
					return true;
				}
			}
		});
		
		assertThat("XML config not found",
				   foundObjects,
				   hasItem("dm_xml_config"));
		
		// check that depth-first walk worked - we should find the xml
		// config before the Presets folder
		assertThat("The xml config was found after the Presets folder",
				   foundObjects.indexOf("dm_xml_config"),
				   is(lessThan(foundObjects.indexOf("Presets"))));
		
		// shouldn't be found cos walk was terminated
		// after finding the 'Presets' folder
		assertThat("Workflow Customizations found",
				   foundObjects,
				   not(hasItem("Workflow Customizations")));
		
		DctmCommonsTestUtil.releaseSession();
	}
	
	/**
	 * Setup routine.
	 */
	@Before
	public void before() throws DfException {
		objectHelper = ObjectHelper.getInstance();
	}
	
	/**
	 * Teardown routine.
	 */
	@After
	public void after() throws DfException {
	}

}
